package ltd.zouzheng.myutils.structure;

import java.util.*;

/**
 * 计数集合
 * 用于统计元素出现的次数
 *
 * @author zouzheng
 * @date 2021/4/13
 */
public class CountSet<E> extends AbstractCollection<E> implements Collection<E> {

    private Map<E, Integer> map;

    public CountSet(){
        map = new HashMap<>();
    }

    public CountSet(Map<E, Integer> map){
        if(null == map){
            this.map = new HashMap<>();
        }else{
            this.map = map;
        }
    }

    public CountSet(Collection<E> collection){
        map = new HashMap<>();
        addAll(collection);
    }

    /**
     * 放入元素，并进行计数
     * null 也会进行计数
     *
     * @author zouzheng
     * @date 2021/4/13
     */
    public int addOne(E e){
        Integer i = map.get(e);
        if(null == i){
            map.put(e, 1);
        }else{
            map.put(e, i + 1);
        }
        return getCount(e);
    }

    /**
     * 将计数的元素直接从元素中删除
     * 成功从集合中删除元素返回 true
     * 如果集合中不存在删除的元素返回 false
     * @author zouzheng
     * @date 2021/4/13
     */
    @Override
    public boolean remove(Object o) {
        return map.remove(o) != null;
    }

    /**
     * 计数器减1，减到0为止，不会出现负数
     *
     * @author zouzheng
     * @date 2021/4/13
     */
    public int minusOne(E e){
        Integer i = map.get(e);
        if(null == i || 0 == i){
            return 0;
        }else{
            map.put(e, i - 1);
        }
        return getCount(e);
    }

    public int getCount(E e){
        Integer integer = map.get(e);
        return null == integer ? 0 : integer;
    }

    /**
     * 获取指定数值的元素集合
     * @author zouzheng
     * @date 2021/4/13
     */
    public CountSet<E> getByCount(int count){
        Map<E, Integer> _map = new HashMap<>();
        Iterator<E> iterator = iterator();
        while(iterator.hasNext()){
            E next = iterator.next();
            if(count == getCount(next)){
                _map.put(next, count);
            }
        }

        return new CountSet<>(_map);
    }

    /**
     * 删除集合中指定数值的元素
     * @author zouzheng
     * @date 2021/4/13
     */
    public boolean removeByCount(int count){
        boolean modified = false;
        Iterator<E> iterator = iterator();
        while(iterator.hasNext()){
            if(count == getCount(iterator.next())){
                iterator.remove();
                modified = true;
            }
        }

        return modified;
    }

    /**
     * 删除集合中指定数值,除外的所有元素
     * @author zouzheng
     * @date 2021/4/13
     */
    public boolean removeByNotCount(int count){
        boolean modified = false;
        Iterator<E> iterator = iterator();
        while(iterator.hasNext()){
            if(count != getCount(iterator.next())){
                iterator.remove();
                modified = true;
            }
        }

        return modified;
    }

    public int size(){
        return map.size();
    }

    @Override
    public boolean isEmpty() {
        return map.isEmpty();
    }

    @Override
    public boolean contains(Object o) {
        return map.containsKey(o);
    }

    @Override
    public Iterator<E> iterator() {
        return map.keySet().iterator();
    }

    @Override
    public boolean add(E e) {
        return addOne(e) != 0;
    }

    @Override
    public String toString() {
        return map.toString();
    }

}
